﻿package {
	import flash.display.*;
	import flash.geom.ColorTransform;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	public class Game extends Sprite {
		private var llkMC:Sprite;
		private var IconArray:Array;
		private var randomArray:Array;
		private var randomTempArray:Array;
		private var pressArray:Array;
		private var findtoarr:Array;
		private var firsti:Array;
		private var tttArray:Array;
		private var patharray:Array;


		private var iconTypes:uint;
		private var pathcnt:uint;
		private var blockCount:uint;
		private var xIcons:uint;
		private var yIcons:uint;
		private var totalIcons:uint;
		private var iconLeft:uint;
		private var lineWidth:uint;
		private var xLineStart:int;
		private var yLineStart:int;
		private var llkWidth:uint;
		private var timeout:Number;
		private var leftTime:Number;
		private var score:uint;
		private var alpha0flag:uint;
		private var lineflag:Boolean;
		private var hinti:int;
		private var hintj:int;

		private var hintBtn:llkBtn;
		private var randomBtn:llkBtn;
		private var resetBtn:llkBtn;
		private var scoreBtn:llkBtn;
		private var clockBar:TimeCount;
		private var llkTimer:Timer;

		public function Game():void {
			addChilds();
			init();
			SetIcons();
			initTimer();
		}
		public function start():void {
			addChild(llkMC);
			llkTimer.start();
		}
		private function addChilds():void {

			resetBtn=new llkBtn(50,20,false,true,resetBtnClick);
			addChild(resetBtn);
			hintBtn=new llkBtn(138,20,false,true,hintBtnClick);
			addChild(hintBtn);
			randomBtn=new llkBtn(190,20,false,true,randomBtnClick);
			addChild(randomBtn);
			scoreBtn=new llkBtn(350,20,false,false);
			addChild(scoreBtn);
			hintBtn.text="提示";
			resetBtn.text="重新开始";
			randomBtn.text="洗牌";
			randomBtn.text2="3";
			scoreBtn.text="SCORE ";
			scoreBtn.text2=0;
			clockBar=new TimeCount  ;
			addChild(clockBar);
			clockBar.width=100;
			clockBar.height=100;
			clockBar.x=450;
			clockBar.y=15;
		}
		private function init():void {
			xIcons=6;
			yIcons=3;
			iconTypes=9;
			totalIcons=xIcons*yIcons;
			iconLeft=totalIcons;
			lineWidth=60;
			llkWidth=48;
			xLineStart=(490-(lineWidth-llkWidth)-xIcons*lineWidth)/2;
			yLineStart=(288-(lineWidth-llkWidth)-yIcons*lineWidth)/2.6+50;
			score=0;
			hinti=-1;
			hintj=-1;
			pressArray=new Array("-1","");
			randomArray=SetRandomArray(totalIcons);


			timeout=60;
			leftTime=0.2;
			lineflag=false;
			clockBar.gotoAndStop(1);
		}
		private function initTimer():void {
			var repeat:int=clockBar.totalFrames;
			var interval:int=timeout*1000/repeat;
			llkTimer=new Timer(interval);
			llkTimer.addEventListener(TimerEvent.TIMER,timerHandler);
		}
		private function possible(a:int,b:int):Boolean {
			tttArray=new Array(yIcons+2);
			var i:uint;
			var j:uint;
			for (i=0; i<yIcons+2; i++) {
				tttArray[i]=new Array(xIcons+2);
				for (j=0; j<xIcons+2; j++) {
					if (i==0||i==yIcons+1||j==0||j==xIcons+1) {
						tttArray[i][j]=-1;
					} else {
						if (IconArray[(i-1)*xIcons+j-1].alpha==.3||IconArray[(i-1)*xIcons+j-1].visible==false) {//已点击
							tttArray[i][j]=-1;
						} else {
							tttArray[i][j]=IconArray[(i-1)*xIcons+j-1].iconFrame+1;
						}
					}
				}
				//trace(tttArray[i]);
			}
			findsteparr=new Array  ;
			findtoarr=new Array  ;
			firsti=new Array  ;
			if (findway(Number(Math.floor(a/xIcons+1)),Number(a%xIcons+1),Number(Math.floor(b/xIcons+1)),Number(b%xIcons+1),0,0,0)) {
				//trace(_global.pathcnt);
				//trace(_global.patharray);
				return true;
			} else {
				return false;
			}
		}

		function findway(ax:int,ay:int,bx:int,by:int,to:int,step:int,lev:int):Boolean {//ax，bx表示行，ay，by表示列
			lev++;
			var areturn:Boolean=false;
			var nextstep:int;
			findsteparr[lev]=step;
			findtoarr[lev]=to;
			//trace("a(" + ax + "," + ay + ") b(" + bx + "," + by + ") |" + findtoarr[lev] + "," + findsteparr[lev]);
			if (step==4) {
				//trace("返回1");
				return false;
			}
			var firstto:Array=new Array(4);
			if (ax>bx) {
				firstto[0]=1;
				if (ay>=by) {
					firstto[1]=3,firstto[2]=4;
				}
				if (ay<by) {
					firstto[1]=4,firstto[2]=3;
				}
				firstto[3]=2;
			}
			if (ax<bx) {
				firstto[0]=2;
				if (ay>=by) {
					firstto[1]=3,firstto[2]=4;
				}
				if (ay<by) {
					firstto[1]=4,firstto[2]=3;
				}
				firstto[3]=1;
			}
			if (ax==bx) {
				if (ay>by) {
					firstto[0]=3,firstto[1]=4;
				}
				if (ay<by) {
					firstto[0]=4,firstto[1]=3;
				}
				firstto[2]=1,firstto[3]=2;
			}
			//trace(firstto);
			var returnflag:Boolean=false;
			if (step==3) {
				switch (to) {
					case 1 :
						if (ax-1==bx&&ay==by) {
							returnflag=true;
						}
						break;
					case 2 :
						if (ax+1==bx&&ay==by) {
							returnflag=true;
						}
						break;
					case 3 :
						if (ax==bx&&ay-1==by) {
							returnflag=true;
						}
						break;
					case 4 :
						if (ax==bx&&ay+1==by) {
							returnflag=true;
						}
				}
			} else if (ax-1==bx&&ay==by||ax+1==bx&&ay==by||ax==bx&&ay-1==by||ax==bx&&ay+1==by) {
				returnflag=true;
			}
			//trace("段2.5");
			if (returnflag==true) {
				patharray[pathcnt]=new Array  ;
				patharray[pathcnt][0]=ax;
				patharray[pathcnt++][1]=ay;
				//trace("返回2");
				return true;
			}
			//trace("段3");
			for (firsti[lev] = 0; firsti[lev] < 4; firsti[lev]++) {;
			//trace("for"+firsti[lev]);
			switch (firstto[firsti[lev]]) {
				case 1 :
					//trace(1,ax,ay);
					if (ax>0) {
						//trace(1,ax,ay,tttArray[ax-1][ay]);
						if (tttArray[ax-1][ay]<0&&areturn!=1) {
							//trace(1,ax,ay);
							if (findtoarr[lev]!=1&&findsteparr[lev]>=0) {
								nextstep=step+1;
							} else {
								nextstep=step;
							}
							if (to!=2) {
								if (findtoarr[lev]==1&&findsteparr[lev]==3) {
									areturn=findway(ax-1,ay,bx,by,1,step,lev);
								} else {
									areturn=findway(ax-1,ay,bx,by,1,nextstep,lev);
								}
							}
						}
					}
					break;
				case 2 :
					//trace(2,ax,ay);
					if (ax<yIcons+1) {
						//trace(2,ax,ay,tttArray[ax+1][ay]);
						if (tttArray[ax+1][ay]<0&&areturn!=1) {
							//trace(2,ax,ay);
							if (findtoarr[lev]!=2&&findsteparr[lev]>=0) {
								nextstep=step+1;
							} else {
								nextstep=step;
							}
							if (to!=1) {
								if (findtoarr[lev]==2&&findsteparr[lev]==3) {
									areturn=findway(ax+1,ay,bx,by,2,step,lev);
								} else {
									areturn=findway(ax+1,ay,bx,by,2,nextstep,lev);
								}
							}
						}
					}
					break;
				case 3 :
					//trace(3,ax,ay);
					if (ay>0) {
						//trace(3,ax,ay,tttArray[ax][ay-1]);
						if (tttArray[ax][ay-1]<0&&areturn!=1) {
							//trace(3,ax,ay);
							if (findtoarr[lev]!=3&&findsteparr[lev]>=0) {
								nextstep=step+1;
							} else {
								nextstep=step;
							}
							if (to!=4) {
								if (findtoarr[lev]==3&&findsteparr[lev]==3) {
									areturn=findway(ax,ay-1,bx,by,3,step,lev);
								} else {
									areturn=findway(ax,ay-1,bx,by,3,nextstep,lev);
								}
							}
						}
					}
					break;
				case 4 :
					//trace(4,ax,ay);
					if (ay<xIcons+1) {
						//trace(4,ax,ay,tttArray[ax][ay+1]);
						if (tttArray[ax][ay+1]<0&&areturn!=1) {
							//trace(4,ax,ay);
							if (findtoarr[lev]!=4&&findsteparr[lev]>=0) {
								nextstep=step+1;
							} else {
								nextstep=step;
							}
							if (to!=3) {
								if (findtoarr[lev]==4&&findsteparr[lev]==3) {
									areturn=findway(ax,ay+1,bx,by,4,step,lev);
								} else {
									areturn=findway(ax,ay+1,bx,by,4,nextstep,lev);
								}
							}
						}
					}
			}
		}
		//trace("段4");
		if (areturn==true) {
			patharray[pathcnt]=new Array  ;
			patharray[pathcnt][0]=ax;
			patharray[pathcnt++][1]=ay;
		}
		//trace("段5");
		//trace("返回3"+areturn);
		return areturn;
	}
	private function llkpress(e:MouseEvent) {
		if (lineflag==true) {
			return;
		}
		var theicon:llkIcon=e.currentTarget;
		var i:int;
		if (pressArray[0]=="-1") {
			pressArray[0]=theicon.iconFrame+1;
			pressArray[1]=theicon.iconid;
			theicon.alpha=.3;
		} else {
			if (pressArray[0]==theicon.iconFrame+1&&pressArray[1]!=theicon.iconid) {
				patharray=new Array  ;
				pathcnt=0;
				if (possible(pressArray[1],theicon.iconid)) {
					theicon.alpha=.3;
					alpha0flag=theicon.iconid;
					theicon.enabled=false;
					randomArray[pressArray[1]]=-1;
					randomArray[theicon.iconid]=-1;
					pressArray[0]="-1";
					IconArray[pressArray[1]].enabled=false;

					//update
					drawline(theicon.iconid);

				} else {
					IconArray[pressArray[1]].alpha=1;
					pressArray[0]="-1";
				}
			} else {
				IconArray[pressArray[1]].alpha=1;
				pressArray[0]="-1";
			}
		}
	}
	private function randomBtnClick(e:MouseEvent=null) {
		clearhint();

		washcards();
	}
	private function washing():void {
		var tempcntarray=new Array  ;//新数组的下标，洗牌用
		var tempcnt2array=new Array  ;//新数组的值，洗牌用
		var cnt:uint;
		var totalcnt:uint=0;
		for (cnt=0; cnt<totalIcons; cnt++) {
			if (randomArray[cnt]>=0) {
				tempcntarray[totalcnt]=cnt;
				tempcnt2array[totalcnt]=IconArray[cnt].iconFrame-1;
				totalcnt++;
			}
		}
		randomTempArray=SetRandomArray(totalcnt);
		var llkx:Number=xLineStart;
		var llky:Number=yLineStart;
		var llki:uint;
		cnt=0;
		for (llki=0; llki<totalIcons; llki++) {
			if (llki%xIcons==0) {
				llkx=xLineStart;
				llky+=lineWidth;
			}
			llkx+=lineWidth;
			if (llki==tempcntarray[cnt]) {
				IconArray[llki].iconFrame=(tempcnt2array[randomTempArray[cnt]]+1);
				//trace("random",llki,(tempcnt2array[randomTempArray[cnt]]+1));
				randomArray[llki]=tempcnt2array[randomTempArray[cnt]];
				cnt++;
			}
		}
	}
	private function hintBtnClick(e:MouseEvent=null) {
		patharray=new Array  ;
		pathcnt=0;
		trace(randomArray);
		for (hinti=0; hinti<totalIcons; hinti++) {
			if (randomArray[hinti]==-1) {
				hinti++;
			}
			for (hintj=hinti+1; hintj<totalIcons; hintj++) {
				if (randomArray[hintj]!=-1&&randomArray[hintj]%iconTypes==randomArray[hinti]%iconTypes) {
					trace(hinti,hintj);
					if (possible(hinti,hintj)) {
						IconArray[hinti].transform.colorTransform=new ColorTransform(1,1,1,1,90,10,50,0);
						IconArray[hintj].transform.colorTransform=new ColorTransform(1,1,1,1,90,10,50,0);
						return true;
					}
				}
			}
		}
		hinti=-1;
		hintj=-1;
		clearhint();
		return false;
	}
	private function resetBtnClick(e:MouseEvent) {
		init();
		SetIcons();
		llkTimer.reset();
		llkTimer.start();
	}
	private function SetIcons():void {
		if (llkMC==null) {
			llkMC=new MovieClip  ;
			IconArray=new Array  ;
		}
		var llki:uint;
		var llkx:Number=xLineStart;
		var llky:Number=yLineStart;
		for (llki=0; llki<totalIcons; llki++) {
			if (llki%xIcons==0) {
				llkx=xLineStart,llky+=lineWidth;
			}
			llkx+=lineWidth;
			if (IconArray[llki]==null) {
				IconArray[llki]=new llkIcon(llki,randomArray[llki]%iconTypes,llkWidth,llkx,llky,llkpress);
				llkMC.addChild(IconArray[llki]);
			} else {
				IconArray[llki].resetllkIcon(llki,randomArray[llki]%iconTypes,llkWidth,llkx,llky);
			}
		}
	}
	private function SetRandomArray(len:uint):Array {
		var randomarray=new Array(len);
		var i:uint;
		var temp:int;
		randomarray[0]=Math.floor(Math.random()*len);
		for (i=1; i<len; i++) {
			temp=-1;
			while (temp==-1) {
				temp=Math.floor(Math.random()*len);
				for (var j=0; j<i; j++) {
					if (temp==randomarray[j]) {
						temp=-1;
					}
				}
				if (temp!=-1) {
					randomarray[i]=temp;
				}
			}
		}
		trace(randomarray);
		return randomarray;
	}
	private function timerHandler(event:TimerEvent):void {
		clockBar.nextFrame();
	}
	private function drawline(iconid):void {
		var i:int;
		llkMC.graphics.lineStyle(2,0xFFD700);
		llkMC.graphics.moveTo(Number(pressArray[1]%xIcons+1)*lineWidth+xLineStart+llkWidth/2,Number(Math.floor(pressArray[1]/xIcons+1))*lineWidth+yLineStart+llkWidth/2);
		for (i=pathcnt-1; i>=0; i--) {
			llkMC.graphics.lineTo(patharray[i][1]*lineWidth+xLineStart+llkWidth/2,patharray[i][0]*lineWidth+yLineStart+llkWidth/2);
		}
		llkMC.graphics.lineTo(Number(iconid%xIcons+1)*lineWidth+xLineStart+llkWidth/2,Number(Math.floor(iconid/xIcons+1))*lineWidth+yLineStart+llkWidth/2);
		trace("line "+patharray,pathcnt-1);
		var lineTimer:Timer=new Timer(leftTime*1000,1);
		lineTimer.addEventListener(TimerEvent.TIMER_COMPLETE,lineTimerHandler);
		lineTimer.start();
		lineflag=true;
		clockBar.prevFrame();
	}
	private function lineTimerHandler(event:TimerEvent):void {
		clearhint();
		iconLeft-=2;
		if (iconLeft==0) {
			END();
		}
		if (clockBar.currentFrame>8) {
			clockBar.gotoAndStop(clockBar.currentFrame-8);
		}
		score+=10;
		scoreBtn.text2=score;
		llkMC.graphics.clear();
		IconArray[alpha0flag].visible=false;
		IconArray[pressArray[1]].visible=false;
		event.target.removeEventListener(TimerEvent.TIMER_COMPLETE,lineTimerHandler);
		lineflag=false;
	}
	private function washcards():void {
		var washTimer:Timer=new Timer(20,5);
		washTimer.addEventListener(TimerEvent.TIMER,washTimingHandler);
		washTimer.addEventListener(TimerEvent.TIMER_COMPLETE,washTimerHandler);
		washTimer.start();
	}
	private function washTimingHandler(event:TimerEvent):void {
		washing();
		event.updateAfterEvent();
	}
	private function washTimerHandler(event:TimerEvent):void {
		event.target.removeEventListener(TimerEvent.TIMER,washTimingHandler);
		event.target.removeEventListener(TimerEvent.TIMER_COMPLETE,lineTimerHandler);
	}
	private function clearhint():void {
		trace(hinti);
		if (hinti!=-1) {
			IconArray[hinti].transform.colorTransform=new ColorTransform();
		}
		if (hintj!=-1) {
			IconArray[hintj].transform.colorTransform=new ColorTransform();
		}
		hinti=-1;
		hintj=-1;
	}
	private function END():void {
		llkTimer.stop();
		score+=(clockBar.totalFrames - clockBar.currentFrame);
		scoreBtn.text2=score;
	}
}
}